# coding: utf8

import random
import string
from django.http import HttpResponse
from django.shortcuts import render
from rest_framework import viewsets, status
from rest_framework.response import Response
from rest_framework.views import APIView
from mall.models import ProductInformation
from tools.common_functions import aes_decrypt, send_verification_mail, do_phone_verification, send_phone_vcode
from tools.common_vars import aesPrivateKey
from users.models import UsersInformation, PersonalDetails, MyFavorite
from users.serializer import UserInfSerializer, PersonalProfileSerializer
from redis import StrictRedis


class PersonalProfileView(viewsets.ModelViewSet):
    """
    接收前端发送的数据, 新增/更新数据库
    """

    queryset = PersonalDetails.objects.all()
    serializer_class = PersonalProfileSerializer


def edit_userinfo(request):
    """
    function: 返回用户个人信息详情便捷界面
    :param request:
    :return:
    """

    # 查询数据库, 获取这个用户的详细数据
    user_name = request.GET.get("username")
    user_info = UsersInformation.objects.filter(user_name=user_name).values()[0]
    user_id = user_info.get("user_id")
    user_detail_info = PersonalDetails.objects.filter(user_id=user_id).values()[0]

    birthday = user_detail_info.get("birthday").strftime("%Y-%m-%d")
    gender = 1 if user_detail_info.get("gender") else 0

    content_data = {
        "title": "编辑个人资料",
        "hide_bottom": True,
        "hide_top": True,
        "username": user_name,
        "nickname": user_detail_info.get("nickname"),
        "personal_profile": user_detail_info.get("personal_profile"),
        "birthday": birthday,
        "gender": gender,
    }

    return render(request, "users/edit_userinfo.html", content_data)


def check_email_activation(request):
    """
    function: 检查邮箱是否已被激活, 若已激活, 跳转到首页;  若没有激活, 弹窗提示
    :return:
    """

    email = request.GET.get("email")
    username = request.GET.get("username")

    # 找出, 用户名和邮箱同时满足的一行记录
    user_info = UsersInformation.objects.filter(user_name=username, email=email).values()
    if len(user_info) > 0:
        vf_email = user_info[0].get("vf_mail")

        if vf_email:
            # 如果此邮箱已经激活, 带参数回到首页
            content_data = {
                "title": "秀出自我",
                "hide_bottom": True,
                "username": username,
                "login_flag": True
            }

            return render(request, "homepage/homepage.html", content_data)

        else:
            # 如果此邮箱没有激活, 需要提示用户
            content_data = {
                "hide_top": True,
                "title": "请前往邮箱激活 !",
                "email": email,
                "username": username,
                "hide_tip": False
            }
            return render(request, "login/email_activation_to_be_confirmed.html", content_data)


def waiting_for_email_activation(request):
    """
    function: 返回等待邮箱确认的界面
    :return:
    """

    email = request.GET.get("email")
    username = request.GET.get("username")

    content_data = {
        "hide_top": True,
        "title": "请前往邮箱激活 !",
        "email": email,
        "username": username,
        "hide_tip": True
    }
    return render(request, "login/email_activation_to_be_confirmed.html", content_data)


class EmailView(APIView):
    """
    邮箱有效性校验
    """

    def get(self, request):
        """
        GET    检索数据/获取数据/校验数据
        function: 响应 GET 请求, 校验用户的邮箱
        :param request:
        :return:
        """

        token = request.GET.get("token")
        user_id = request.GET.get("id")

        # 从redis数据库中获取token
        sr = StrictRedis()
        redis_token = sr.get(user_id).decode()  # 加上decode, 是为了将bytes转换为string

        result = False
        if redis_token == token:
            # 如果确实是这个用户, 那么就操作数据库, 修改此邮箱验证完成
            user_info = UsersInformation.objects.filter(user_id=user_id)[0]

            user_info.vf_mail = True
            user_info.save()
            result = True

        # 美化一下返回的界面
        content_data = {
            "title": "邮箱激活结果",
            "hide_bottom": True,
            "res": "",
            "hide_top": True,
        }

        if result:
            content_data["res"] = "成功"
            return render(request, "login/show_res_of_email_activation.html", content_data)

        else:
            content_data["res"] = "失败"
            return render(request, "login/show_res_of_email_activation.html", content_data)


class ShowLogin(APIView):
    def get(self, request):
        """
        function: 这里的get, 表示前端如果发送的是 get 请求, 就会使用这个方法
        :param request:
        :return:
        """

        content_data = {
            "login_js_path": "/static/js/login.js",
            "title": "登录",
            "hide_top": True
        }
        return render(request, "login/login.html", content_data)


class Login(APIView):
    """
    用户登录

    前端发送的请求类型, 必须要符合以下要求和标准
    POST	创建数据
    GET	    检索数据/获取数据
    PUT	    更新数据
    DELETE	删除数据
    """

    def get(self, request):
        """
        function： 从数据库中获取当前所有用户信息, 对比用户输入信息是否存在, 若存在, 返回相应界面，
        若不存在, 提示用户, 用户名/密码可能有误
        :return:
        """

        # 获取用户输入的用户名和密码
        user_name = request.GET.get("user_name")
        password = request.GET.get("password")  # 加密后的

        # 判断用户名是否在数据库中
        user_info = UsersInformation.objects.filter(user_name=user_name)
        if len(user_info) > 0:
            # 如果在, 解密密码
            new_passwd = aes_decrypt(aesPrivateKey, password)

            # 再判断密码是否在数据库中
            passwd_info = UsersInformation.objects.filter(password=new_passwd)

            if len(passwd_info) > 0:
                return Response({"code": 200, "msg": "login success"})

            else:
                return Response({"code": 200, "msg": "wrong password"})

        else:
            return Response({"code": 200, "msg": "user does not exist"})


class Register(APIView):
    """
    注册的视图类
    """

    def get(self, request, *args):
        content_data = {
            "register_js_path": "/static/js/register.js",
            "title": "注册",
            "hide_top": True
        }
        return render(request, "login/my_layui_register.html", content_data)

    def post(self, request):
        """
        function: 接收post请求, 注册新的用户
        注册要邮箱验证, 或者 手机验证码验证
        :param request: 请求报文
        :return:
        """

        receive_data = request.data.copy()
        password = receive_data.get("password")

        user_id = receive_data.get("user_id")
        to_email = receive_data.get("email").strip()

        # 同时也写入一行用户个人详情信息的默认信息
        personal_model = PersonalDetails()
        personal_model.user_id = user_id
        personal_model.birthday = "2018-08-18"
        personal_model.nickname = receive_data.get("user_name")
        personal_model.save()

        # 邮箱验证
        if to_email:
            # 用户填写的有邮箱, 再发送
            send_verification_mail(to_email, user_id)

            new_passwd = aes_decrypt(aesPrivateKey, password)
            receive_data["password"] = new_passwd

            serializer = UserInfSerializer(data=receive_data)

            if serializer.is_valid():
                serializer.save()
                return Response(serializer.data, status=status.HTTP_201_CREATED)
            else:
                return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

        else:
            # 手机验证码验证
            verification_phone_num = receive_data.get("phone_num").strip()
            if verification_phone_num:
                # 如果手机号不为空
                phone_vcode = receive_data.get("phone_vcode").strip()

                # todo 验证手机号
                res = do_phone_verification(phone_vcode)

                if res:
                    new_passwd = aes_decrypt(aesPrivateKey, password)
                    receive_data["password"] = new_passwd

                    serializer = UserInfSerializer(data=receive_data)

                    if serializer.is_valid():
                        serializer.save()
                        return Response(serializer.data, status=status.HTTP_201_CREATED)
                    else:
                        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

                else:
                    return Response({"code": 400,
                                     "msg": "发送手机验证码失败 !\n请检查手机号 !"})

            else:
                return Response({"code": 400, "msg": "手机号/邮箱 至少须有一个 !"})


class RegisterViewSet(viewsets.ModelViewSet):
    """
    用户注册的及时验证操作
    """

    queryset = UsersInformation.objects.all()
    serializer_class = UserInfSerializer

    def get_queryset(self):
        """
        function: 检测用户注册时, 发送的请求
        :return:
        """

        email = self.request.query_params.get("email", 0)
        if email:
            # 查询数据库中是否有这个email, 返回查询结果
            user_info = UsersInformation.objects.filter(email=email)
            return user_info

        phone_num = self.request.query_params.get("phone_num", 0)
        if phone_num:
            # 查询数据库中是否有这个phone_num, 返回查询结果
            user_info = UsersInformation.objects.filter(phone_num=phone_num)
            return user_info

        user_name = self.request.query_params.get("user_name", 0)
        if user_name:
            # 查询数据库中是否有这个user_name, 返回查询结果
            user_info = UsersInformation.objects.filter(user_name=user_name)
            return user_info


class PhoneVerificationCodeView(APIView):
    """获取手机验证码"""

    def post(self, request):
        phone_num = request.data.get('phone_num')
        # 生成手机验证码
        code = "".join(random.sample([x for x in string.digits], 6))

        sms_status = send_phone_vcode(code, phone_num)
        return HttpResponse(sms_status)


class UserCenter(APIView):
    """
    用户中心
    """

    def get(self, request):
        """
        function: 返回用户中心界面
        :param request:
        :return:
        """

        # 查询数据库, 获取这个用户的详细数据
        user_name = request.GET.get("username")
        user_info = UsersInformation.objects.filter(user_name=user_name).values()[0]
        user_id = user_info.get("user_id")
        user_detail_info = PersonalDetails.objects.filter(user_id=user_id).values()[0]

        response_dict = {
            "hide_top": True,
            "username": user_name,
            "title": f"{user_name}的个人中心",
            "hide_bottom": True,
            "personal_profile": user_detail_info.get("personal_profile"),
            "registration_time": user_info.get("registration_time")
        }

        return render(request, "users/user_center.html", response_dict)


class MyFavoriteView(APIView):
    """
    我的收藏
    """

    def get(self, request):
        """
        function: 这里的get, 表示前端如果发送的是 get 请求, 就会使用这个方法
        :param request:
        :return:
        """

        content_data = {
            "login_js_path": "/static/js/login.js",
            "title": "我的收藏",
            "login_flag": True,
            "hide_top": False,
            "hide_bottom": True,
            "product_inf": {}
        }

        # 查询数据库, 获取收藏的商品信息
        user_name = request.GET.get("username")
        content_data["username"] = user_name

        user_info = UsersInformation.objects.filter(user_name=user_name).values()[0]
        user_id = user_info.get("user_id")
        favorite_info = MyFavorite.objects.filter(user_id=user_id).values()

        # 根据收藏信息, 获取产品id, 再根据产品id, 获取到产品名和产品简介
        for favorite_dict in favorite_info:
            product_id = favorite_dict.get("product_id")
            product_info = ProductInformation.objects.filter(product_id=product_id).values()[0]
            product_name = product_info.get("product_name")
            product_brief_introduction = product_info.get("product_brief_introduction")
            content_data["product_inf"][product_name] = product_brief_introduction

        return render(request, "users/my_favorite.html", content_data)


class MyOrder(APIView):
    """
    todo 我的订单
    """

    pass
